#pragma once

typedef void (*FnAsync)(WPARAM, LPARAM, WPARAM, LPARAM);

struct AsyncParam
{
	WPARAM	_wParam;
	LPARAM	_lParam;
	FnAsync	_then;
	DWORD	_ret;
	WPARAM	_wParamSrc;
	LPARAM	_lParamSrc;

	AsyncParam(WPARAM wParam, LPARAM lParam, FnAsync then = NULL, DWORD ret = 0, WPARAM wParamSrc = 0, LPARAM lParamSrc = 0);
};

class xThread
{
public:
	xThread();
	virtual ~xThread();
protected:
	DWORD	m_dwThreadID;
	HANDLE	m_hThread;
private:
	static DWORD WINAPI ThreadProc(LPVOID lpParam);
protected:	
	virtual void OnThreadProc(DWORD wParam, LPVOID lpParam);
	virtual BOOL OnMessageLoop(MSG &msg);
	virtual BOOL PreTranslateMessage(MSG &msg);
	virtual void OnAsyncMsg(DWORD dwFuncID, WPARAM wParam, LPARAM lParam, DWORD nThreadIDReturn, FnAsync then);
public:
	DWORD	CreateThread(WPARAM wParam = 0);
	void	Destroy(BOOL bSync = FALSE);
	void	Attach(DWORD dwThreadID);
	void	Detach();
};	

AsyncParam *Async(DWORD nThreadID, DWORD nFuncID, WPARAM wParam = 0, LPARAM lParam = 0, DWORD nThreadIDReturn = 0);
void AsyncReturn(DWORD nThreadID, FnAsync then, DWORD nFuncID, WPARAM wParam = 0, LPARAM lParam = 0, WPARAM wParamSrc = 0, LPARAM lParamSrc = 0);

//#define WM_ASYNC_MSG		(WM_USER + 0x1000)
//#define WM_ASYNCRET_MSG	(WM_USER + 0x2000)
